package com.shensi.common.core.utils;

import com.alibaba.fastjson.JSONObject;
import com.shensi.common.core.constant.Constants;
import com.shensi.common.core.constant.HttpStatus;
import com.shensi.common.core.domain.entity.SysUser;
import com.shensi.common.core.domain.model.LoginUser;
import com.shensi.common.core.exception.CustomException;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtParser;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.SignatureException;
import io.jsonwebtoken.UnsupportedJwtException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;

/**
 * 安全服务工具类
 *
 * @author qujia
 */
@Component
public class SecurityUtils {

    /**
     * 令牌秘钥
     */
    @Value("${token.secret}")
    private String secret;
    private static String SECRET;

    @PostConstruct
    public void getSecret(){
        SECRET = secret;
    }

    /**
     * 获取用户账户
     **/
    public static String getUsername() {
        try {
            return getLoginUser().getUsername();
        } catch (Exception e) {
            throw new CustomException("获取用户账户异常", HttpStatus.UNAUTHORIZED);
        }
    }

    /**
     * 获取用户
     **/
    public static LoginUser getLoginUser() {
        try {
            return (LoginUser) getAuthentication().getPrincipal();
//            return getUserByToken();
        } catch (Exception e) {
            throw new CustomException("获取用户信息异常", HttpStatus.UNAUTHORIZED);
        }
    }

    /**
     * 获取Authentication
     */
    public static Authentication getAuthentication() {
        SecurityContext context = SecurityContextHolder.getContext();
        Authentication authentication = context.getAuthentication();
        return authentication;
    }

    /**
     * 生成BCryptPasswordEncoder密码
     *
     * @param password 密码
     * @return 加密字符串
     */
    public static String encryptPassword(String password) {
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        return passwordEncoder.encode(password);
    }

    /**
     * 判断密码是否相同
     *
     * @param rawPassword     真实密码
     * @param encodedPassword 加密后字符
     * @return 结果
     */
    public static boolean matchesPassword(String rawPassword, String encodedPassword) {
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        return passwordEncoder.matches(rawPassword, encodedPassword);
    }

    /**
     * 是否为管理员
     *
     * @param userId 用户ID
     * @return 结果
     */
    public static boolean isAdmin(Long userId) {
        return userId != null && 1L == userId;
    }


    /**
     * 根据request中的token获取用户账号
     */
   /* public static Long getUserId() {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            Claims memberByToken = getMemberByToken(request);
            return Long.valueOf(String.valueOf(memberByToken.get("userId")));
        } catch (Exception e) {
            throw new CustomException("获取用户ID信息异常", HttpStatus.UNAUTHORIZED);
        }
    }*/

    /*public static String getUserLevel() {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            Claims memberByToken = getMemberByToken(request);
            return String.valueOf(memberByToken.get("userLevel"));
        } catch (Exception e) {
            throw new CustomException("获取等级信息异常", HttpStatus.UNAUTHORIZED);
        }
    }*/

    /*public static Long getEnterpriseId() {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            Claims memberByToken = getMemberByToken(request);
            return Long.valueOf(String.valueOf(memberByToken.get("enterpriseId")));
        } catch (Exception e) {
            throw new CustomException("获取油企信息异常", HttpStatus.UNAUTHORIZED);
        }
    }*/


    /*public static Long getStationId() {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            Claims memberByToken = getMemberByToken(request);
            return Long.valueOf(String.valueOf(memberByToken.get("stationId")));
        } catch (Exception e) {
            throw new CustomException("获取油站信息异常", HttpStatus.UNAUTHORIZED);
        }
    }*/

    /**
     * 根据request中的token获取用户账号
     */
    public static Claims getMemberByToken(HttpServletRequest request) {
        try {
            String accessToken = request.getHeader("X-Access-Token");
            if (StringUtils.isNull(accessToken)){
                accessToken = request.getHeader("Authorization");
            }

            return getClaims(accessToken);
        } catch (Exception e) {

        }
        return null;
    }

    /**
     * 从令牌中获取数据声明
     *
     * @param token 令牌
     * @return 数据声明
     */
    public static Claims getClaims(String token) {

        if (StringUtils.isNotNull(token) && token.startsWith("Bearer")){
            token = token.replace("Bearer ","");
        }
        Claims claims = Jwts.parser()
                .setSigningKey(SECRET)
                .parseClaimsJws(token)
                .getBody();
        return claims;
//        return (String)claims.get(Constants.LOGIN_USER_KEY);
    }

    public static SysUser getLoginSysUser(){
        try
        {
            return getLoginUser().getUser();
        }
        catch (Exception e)
        {
            throw new CustomException("获取用户账户异常", HttpStatus.UNAUTHORIZED);
        }
    }
}
